<?php
namespace app\test\controller;
use think\Db;
use think\Controller;
use app\service\Aop;
use app\service\invoiceService;
use app\service\apiService;
use think\facade\Log;
use invoice\InvoiceApi;
class Invoice extends Controller{
    public function test2(){
        $user_id="2088112618452297";
        $api=new apiService();
        $res=$api->getInvoiceTitleList($user_id);
        var_dump($res);
    }
    public function test(){
        $id="8119";
        $res=$this->gateOrderInvoiceSend($id);
        echo "<pre>";
        var_dump($res);
    }

    public function gateOrderInvoiceSend($id){


        $invoice=Db::table("parkgatebillorder")->where("id",$id)->find();

        if(empty($invoice)){
            return "1";
        }
        $num_back=$invoice['num_back']+1;
        Db::table("parkgatebillorder")
            ->where('id',$invoice["id"])
            ->update([
                "num_back"=>$num_back
            ]);
        $invoiceinfo=$this->gateOrderInvoiceApply($invoice["id"]);

        if($invoiceinfo["errorCode"]=="0"){

            $serviceinfo=(new invoiceService())->parkingInvoice($invoice["parkingNo"]);
            //return $serviceinfo;
            //var_dump($info);
            $data["m_short_name"]=$serviceinfo["m_short_name"];
            $data["sub_m_short_name"]=$serviceinfo["sub_m_short_name"];
            $data["user_id"]=$invoice["user_id"];


            $data["invoice_date"]=$invoiceinfo["invoice_date"];
            $data["sum_amount"]=$invoice["order_money"];
            $data["tax_amount"]=round(($invoice["order_money"]*$serviceinfo["taxrate"])/(1+$serviceinfo["taxrate"]),2);//合计税额，票面上的合计税额
            $data["ex_tax_amount"]=$data["sum_amount"]-$data["tax_amount"];//不含税金额
            $data["item_name"]="餐饮费";
            $data["item_no"]="1010101990000000000";
            $data["item_spec"]="G39";
            $data["item_unit"]="台";
            $data["item_quantity"]="1";
            $data["item_unit_price"]=$data["ex_tax_amount"];
            $data["item_ex_tax_amount"]=$data["ex_tax_amount"];
            $data["item_tax_amount"]=$data["tax_amount"];
            $data["item_sum_amount"]=$data["sum_amount"];
            $data["item_tax_rate"]=$serviceinfo["taxrate"];

            $data["out_trade_no"]=$invoice["out_trade_no"];
            $data["invoice_type"]='BLUE';
            $data["invoice_kind"]='PLAIN';

            $data["invoice_code"]=$invoiceinfo["invoiceCode"];//发票代码，该字段与invoice_no构成一张发票的唯一标识
            $data["invoice_no"]=$invoiceinfo["invoiceNum"];//发票号码，该字段与invoice_code构成一张发票的唯一标识。
            //购买方信息
            $data["title_name"]="个人";
            $data["payer_register_no"]="";//购方税号
            $data["payer_address_tel"]="";
            $data["payer_bank_name_account"]="";

            //销售方信息 根据停车场查询
            $data["payee_register_no"]=$serviceinfo["fp_saler_tax_num"];
            $data["payee_register_name"]=$serviceinfo["name"];
            $data["payee_address_tel"]=$serviceinfo["fp_saler_account"];

            $data["payee_bank_name_account"]=$serviceinfo["bank"];
            $data["check_code"]='';
            //$data["out_invoice_id"]=$info["orderNo"];
            $data["out_invoice_id"]=date("YmdHis").rand(100000,999999);
            $data["ori_blue_inv_code"]='';
            $data["ori_blue_inv_no"]='';
            $data["file_download_type"]='PDF';
            $data["file_download_url"]=$invoiceinfo["invoiceFileUrl"];
            $data["payee"]='';
            $data["checker"]='';
            $data["clerk"]='';
            $data["invoice_memo"]="停车费";
            $data["xtend_fields"]='';

            $api=new apiService();
            $res=$api->invoiceSendDirect(json_encode($data));
            return $res;
            //var_dump($res);
            /*Log::write($res,"invoiceSend",true);
            if(($res->code!="10000")&&($num_back<3)){

                $this->yzl_fsockopen('http://www.aliwgzf.com/index/invoice/gateOrderInvoiceSend',$info);
            }*/
        }else{
            //Log::write($invoiceinfo,"invoiceSend");
        }
    }

    public function gateOrderInvoiceApply($id){
        $invoiceinfo=Db::table('parkgatebillorder')->find($id);

        if($invoiceinfo["invoice_type"]!="3"){
            $res=$this->gateOrderCheckEInvoice($id);
            return $res;
        }
        $serviceinfo=(new invoiceService())->parkingInvoice($invoiceinfo["parkingNo"]);
        //return $serviceinfo;


        //购方手机（开票成功会短信提醒购方，不受推送方式影响）(Y)
        $buyerPhone=$invoiceinfo["buyerPhone"];

        $buyerName=$invoiceinfo["buyerName"];
        $buyerTaxNum=$invoiceinfo["buyerTaxnum"];
        $buyerTel=$invoiceinfo["buyerTel"];
        $buyerAddress=$invoiceinfo["buyerAddress"];
        $buyerAccount=$invoiceinfo["buyerAccount"];

        //订单号
        $orderNo =$invoiceinfo["out_trade_no"];
        //订单时间
        $invoiceDate = date('Y-m-d H:i:s',time());
        $clerk="";
        //订单详情
        //金额
        $money=$invoiceinfo["pay_money"];
        //税率
        $taxrate=$serviceinfo["taxrate"];
        //税额
        $tax=$taxrate*$money;

        $invoiceDetail= "{'goodsName':'车位费','num':'1','price':'{$money}','withTaxFlag':'1','taxRate':'{$taxrate}','tax':'{$tax}'}";

        $timestmp = time();
        $remark=$invoiceinfo["parkingName"]."-支付宝支付";
        //判断access_token是否到期
        $second = strtotime(date('Y-m-d H:i:s',time()))-strtotime($serviceinfo['fp_expires_in']);
        if($second <86400){
            //未过期
            $access_token = $serviceinfo['fp_access_token'];
        }else{
            //过期从新获取
            $res = (new invoiceService())->getToken($serviceinfo['service_id']);
            if(array_key_exists("error",$res)){
                $res["errorCode"]="1";
                $res["error"]= $res["error_description"];
                return $res;
            }
            $access_token = $res['fp_access_token'];
        }

        $webinfo=Db::table("webset")->where("id","1")->find();
        $appKey = $webinfo["appKey"];
        $appSecret = $webinfo["appSecret"];
        $token = $access_token;// please store the token and refresh it before expired
        $taxnum = $serviceinfo["fp_saler_tax_num"];

        $url = "https://sdk.nuonuo.com/open/v1/services"; // change to online domain
        $method = "nuonuo.electronInvoice.requestBilling"; // change to your method
        $senid = uniqid(); // generate your meaningful senid

        $invoiceDate = date('Y-m-d H:i:s',time());
        $orderNo = time().rand(100000,999999);
        $timestmp = time();
        //$buyerName=$invoiceinfo["buyerName"];
        $buyerName="个人";
        //$buyerPhone=$invoiceinfo["buyerPhone"];
        $buyerPhone=1;
        $buyerTaxNum=$invoiceinfo["buyerTaxnum"];
        $buyerTel=$invoiceinfo["buyerTel"];
        $buyerAddress=$invoiceinfo["buyerAddress"];
        $buyerAccount=$invoiceinfo["buyerAccount"];

        //$buyerPhone="188561510";
        $fp_saler_tax_num=$serviceinfo['fp_saler_tax_num'];
        $salerAddress=$serviceinfo['address'];
        $salerTel=$serviceinfo['phone'];
        $salerAddress=$serviceinfo['address'];
        $salerAccount=$serviceinfo['fp_saler_account'];
        $emt="";

        //var_dump($content);
        $body = "{
        \"order\": {
            \"buyerName\": \"$buyerName\",
            \"orderNo\": \"$orderNo\",
            \"buyerTaxNum\": \"$buyerTaxNum\",
            \"buyerTel\": \"$buyerTel\",
            \"buyerAddress\": \"$buyerAddress\",
            \"buyerAccount\": \"$buyerAccount\",
            \"invoiceDate\": \"$invoiceDate\",
            \"clerk\": \"\",
            \"salerTaxNum\": \"$fp_saler_tax_num\",
            \"salerTel\": \"$salerTel\",
            \"salerAddress\": \"$salerAddress\",
            \"salerAccount\": \"$salerAccount\",
            \"invoiceType\": \"1\",
            \"pushMode\": \"1\",
            \"buyerPhone\": \"$buyerPhone\",
            \"remark\": \"$remark\",
            \"invoiceDetail\": [$invoiceDetail],
            \"callBackUrl\": \"http://www.jfzhiwen.com/admin/invoice/callback/\"
            }
        }";

        $result = InvoiceApi::sendPostSyncRequest($url, $senid, $appKey, $appSecret, $token, $taxnum, $method, $body);
        //var_dump($result);
        $result = json_decode($result, true);
        //Log::write($result,"invoiceresult");
        if($result['code'] == 'E0000'){
            $invoiceSerialNum = $result['result']['invoiceSerialNum'];
            $invoice["invoice_serial_num"] = $result['result']['invoiceSerialNum'];
            $invoice["invoice_time"]=date('Y-m-d H:i:s');
            $invoice["invoice_type"]="1";

            $invoice["invoice_date"]=date('Y-m-d');
            $res=Db::table('parkgatebillorder')->where('id', $id)->update($invoice);
            $res=$this->gateOrderCheckEInvoice($id);

            return $res;
        }else{
            $res["errorCode"]="1";
            $res["error"]= $result['describe'];
            return $res;
        }
    }

    //查询发票
    public function gateOrderCheckEInvoice($id){
        //sleep(30);
        //查询发票序列号
        $data=Db::table('parkgatebillorder')->find($id);

        if(!empty($data["invoiceFileUrl"])){
            $data["errorCode"]="0";
            return $data;

        }
        //根据商家id查询开票信息
        $serviceinfo=(new invoiceService())->parkingInvoice($data["parkingNo"]);

        //判断access_token是否到期
        $second = strtotime(date('Y-m-d H:i:s',time()))-strtotime($serviceinfo['fp_expires_in']);
        if($second <86400){
            //未过期
            $access_token = $serviceinfo['fp_access_token'];
        }else{
            //过期从新获取
            $res = (new invoiceService())->getToken($serviceinfo['service_id']);
            if(array_key_exists("error",$res)){
                return $res;
                return $res["error_description"];
            }
            $access_token = $res['fp_access_token'];
        }
        //var_dump($access_token);die;
        $timestmp = time();

        $webinfo=Db::table("webset")->where("id","1")->find();
        $appKey = $webinfo["appKey"];
        $appSecret = $webinfo["appSecret"];
        $token = $access_token;// please store the token and refresh it before expired
        $taxnum = $serviceinfo["fp_saler_tax_num"];

        $url = "https://sdk.nuonuo.com/open/v1/services"; // change to online domain
        $method = "nuonuo.electronInvoice.CheckEInvoice"; // change to your method
        $senid = uniqid(); // generate your meaningful senid
        $body = json_encode(
            array(
                "invoiceSerialNum" => array($data['invoice_serial_num'])
            )
        );

        $result = InvoiceApi::sendPostSyncRequest($url, $senid, $appKey, $appSecret, $token, $taxnum, $method, $body);


        $result = json_decode($result, true);

        if($result['code'] == 'E0000'){
            //return $result['result'][0]['invoiceFileUrl'];
            Db::table("parkgatebillorder")
                ->where('id',$id)
                ->update([
                    "invoiceFileUrl"=>$result['result'][0]['invoiceFileUrl'],
                    "invoiceNum"=>$result['result'][0]["invoiceNum"],
                    "invoiceCode"=>$result['result'][0]['invoiceCode']
                ]);

            $res=Db::table("parkgatebillorder")->where('id',$id)->find();
            $res["errorCode"]="0";
            return $res;
        }else{
            $res["errorCode"]="1";
            $res["error"]= $result['describe'];
            return $res;
            return json(['error' => $result['describe']]);
        }
    }


    public function yzl_fsockopen($url,$post_data=array(),$cookie=array()){
        $url_arr = parse_url($url);
        $port = isset($url_arr['port'])?$url_arr['port']:80;
        if($url_arr['scheme'] == 'https'){
            $url_arr['host'] = 'ssl://'.$url_arr['host'];
        }
        $fp = fsockopen($url_arr['host'],$port,$errno,$errstr,30);
        if(!$fp) return false;
        $getPath = isset($url_arr['path'])?$url_arr['path']:'/index.php';
        $getPath .= isset($url_arr['query'])?'?'.$url_arr['query']:'';
        $method = 'GET';  //默认get方式
        if(!empty($post_data)) $method = 'POST';
        $header = "$method  $getPath  HTTP/1.1\r\n";
        $header .= "Host: ".$url_arr['host']."\r\n";
        if(!empty($cookie)){  //传递cookie信息
            $_cookie = strval(NULL);
            foreach($cookie AS $k=>$v){
                $_cookie .= $k."=".$v.";";
            }
            $cookie_str = "Cookie:".base64_encode($_cookie)."\r\n";
            $header .= $cookie_str;
        }
        if(!empty($post_data)){  //传递post数据
            $_post = array();
            foreach($post_data AS $_k=>$_v){
                $_post[] = $_k."=".urlencode($_v);
            }
            $_post = implode('&', $_post);
            $post_str = "Content-Type:application/x-www-form-urlencoded; charset=UTF-8\r\n";
            $post_str .= "Content-Length: ".strlen($_post)."\r\n";  //数据长度
            $post_str .= "Connection:Close\r\n\r\n";
            $post_str .= $_post;  //传递post数据
            $header .= $post_str;
        }else{
            $header .= "Connection:Close\r\n\r\n";
        }
        fwrite($fp, $header);
        //echo fread($fp,1024);
        usleep(1000); // 这一句也是关键，如果没有这延时，可能在nginx服务器上就无法执行成功
        fclose($fp);
        return true;
    }







    public function ToUrlParam($value){
        $buff = "";
        foreach($value as $k => $v){
            if($k != "sign" &&  !is_array($v)){
                $buff .= $k . "=" . $v . "&";
            }
        }
        $buff = trim($buff, "&");
        return $buff;
    }

    //生成签名
    protected function MakeSign($arr){
        //签名步骤一：按字典序排序参数
        ksort($arr);

        $string = $this->ToUrlParam($arr);
        return $string;
        //签名步骤二：在string后加入KEY
        //签名步骤三：MD5加密
        //$string = md5($string);

        //签名步骤四：所有字符转为大写
        //$result = strtoupper($string);
        return $result;
    }

    protected function verifysign($str){
        $info = $this->object_to_array($str);
        $sign=$info["sign"];
        unset($info["sign"]);
        $str=$this->MakeSign($info);
        $str=iconv("UTF-8","gbk",$str);
        $aop=new Aop();
        $res=$aop->verify($str, urldecode($sign),  $signType = 'RSA');
        return $res;
    }

    //将对象转换成数组
    public function object_to_array($obj){
        $_arr = is_object($obj) ? get_object_vars($obj) :$obj;
        foreach($_arr as $key=>$val){
            if($key !== 'gioouts'){
                if($key !=='isRetryOpen'){
                    $val = (is_array($val) || is_object($val)) ? $this->object_to_array($val):$val;
                    $arr[$key] = $val;
                }else{
                    if($val){
                        $arr[$key] = "true";
                    }else{
                        $arr[$key] = "false";
                    }
                }

            }
        }
        return $arr;
    }
}